# =============================================================================
# April 24 2025
# R code used to produce all results, tables, and figures in the SI Online Appendix F
# Rebecca Cordell
# Unpacking the Role of In-Group Bias in US Public Opinion on Human Rights Violations
# American Journal of Political Science
# https://doi.org/10.7910/DVN/TGAL7M
# =============================================================================

# Clear work environment
rm(list=ls())

# Install Packages
#install.packages("dplyr")
#install.packages("ggplot2")
#install.packages("forcats")
#install.packages("ggpubr")
#install.packages("ggeasy")
#install.packages("lemon")
#install.packages("sandwich")
#install.packages("survey")
#install.packages("lmtest")
#install.packages("remotes")
#remotes::install_version("cregg", version = "0.4.0")

# Required Packages
library("dplyr")
library("ggplot2")
library("forcats")
library("ggpubr")
library("sandwich")
library("survey")
library("lmtest")
library("cregg")
library("ggeasy")
library("lemon")

options(scipen = 999)
options(warn=-1)

# -----------------------------------------------------------------------------
# Read in data
# -----------------------------------------------------------------------------

hr_survey<-read.csv("cordell_ingroupbiashumanrights_data.csv", header=TRUE, stringsAsFactors = FALSE)

# =============================================================================
# Figure F.1: Effect of the Contextual Attributes on Respondents’ Disapproval of the Abuse
# =============================================================================

# Convert regression variables into factors
factor_vars <- c("perp", "agent", "type", "scope", "targ_nonstate",
                 "targ_race", "targ_relig", "targ_citiz",
                 "frame", "elite")
hr_survey[factor_vars] <- lapply(hr_survey[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_f1_m1 <- cregg::cj(hr_survey, outcome1 ~ perp + agent + type + scope + targ_nonstate + targ_race + targ_relig + targ_citiz + frame + elite, id = ~id, estimate = "mm")

# Subset control variables
control_vars <- c("agent","targ_nonstate","type","scope","frame","elite")
fig_f1_m1 <- fig_f1_m1[fig_f1_m1$feature %in% control_vars,]
fig_f1_m1 <- fig_f1_m1[fig_f1_m1$level!="A Democrat member of Congress",]
fig_f1_m1 <- fig_f1_m1[fig_f1_m1$level!="A Republican member of Congress",]

# Model 2
fig_f1_m2 <- cregg::cj(hr_survey, outcome2 ~ perp + agent + type + scope + targ_nonstate + targ_race + targ_relig + targ_citiz + frame + elite, id = ~id, estimate = "mm")

# Subset control variables
fig_f1_m2 <- fig_f1_m2[fig_f1_m2$feature %in% control_vars,]
fig_f1_m2 <- fig_f1_m2[fig_f1_m2$level!="A Democrat member of Congress",]
fig_f1_m2 <- fig_f1_m2[fig_f1_m2$level!="A Republican member of Congress",]

# -----------------------------------------------------------------------------
# Prepare figures
# -----------------------------------------------------------------------------

# Combine models
fig_f1_all <- rbind(fig_f1_m1, fig_f1_m2)

# Create control variable labels
variable_labels <- c(
  "agent" = "Perpetrator (agent)",
  "type" = "Type",
  "scope" = "Scope",
  "targ_nonstate" = "Target (non-state)",
  "frame" = "Framing",
  "elite" = "Elite cue (hro)")
fig_f1_all <- dplyr::bind_rows(
  fig_f1_all,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Recode control variable values
fig_f1_all$level <- recode(fig_f1_all$level,
                           "a civilian militia group" = "Civilian militia group",
                           "a private militia group" = "Private militia group",
                           "the military" = "Military",
                           "the national guard" = "National guard",
                           "the police" = "Police",
                           "suspected terrorists" = "Suspected terrorists",
                           "criminals" = "Criminals",
                           "protesters" = "Protesters",
                           "journalists" = "Journalists",
                           "civilians" = "Civilians",
                           "Type" = "Type",
                           "arbitrary arrest" = "Arbitrary arrest",
                           "disappearance" = "Disappearance",
                           "torture" = "Torture",
                           "extrajudicial killing" = "Extrajudicial killing",
                           "two" = "Two people",
                           "six" = "Six people",
                           "twelve" = "Twelve people",
                           "twenty" = "Twenty people",
                           "none" = "None",
                           "personal" = "Personal",
                           "violent" = "Violent",
                           "The American Civil Liberties Union, an American nonprofit organization," = "ACLU",
                           "Amnesty International, an international nonprofit organization," = "Amnesty international")

# Set factor order
level_order <- c(
  "Perpetrator (agent)", "Civilian militia group", "Private militia group", "Military", "National guard", "Police",
  "Target (non-state)", "Suspected terrorists", "Criminals", "Protesters", "Journalists", "Civilians",
  "Type", "Arbitrary arrest","Disappearance", "Torture", "Extrajudicial killing",
  "Scope", "Two people", "Six people", "Twelve people", "Twenty people",
  "Framing", "None", "Personal", "Violent",
  "Elite cue (hro)", "ACLU", "Amnesty international"
)
fig_f1_all <- fig_f1_all %>%
  mutate(level = factor(level, levels = level_order) %>% fct_rev())

# Separate models
fig_f1_m1 <- filter(fig_f1_all, outcome == "outcome1")
fig_f1_m2 <- filter(fig_f1_all, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create figures
# -----------------------------------------------------------------------------

# Create panel (a) Disapproval forced-choice
fig_f1_m1_plot <- ggplot(fig_f1_m1, aes(x = level, y = estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2)  +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (b) Disapproval ratings-based
fig_f1_m2_plot <- ggplot(fig_f1_m2, aes(x = level, y = estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure F.1
pdf('figure_f1.pdf', width = 8.26, height = 5.82)
ggarrange(fig_f1_m1_plot, NULL, fig_f1_m2_plot,
          nrow = 1, common.legend = T, legend = "bottom", ncol=3, widths = c(1, 0.09, 1))
dev.off()

# =============================================================================
# Figure F.2: Effect of the Contextual Attributes on Respondents’ Willingness to Mobilize Against the Violation
# =============================================================================

# -----------------------------------------------------------------------------
# Calculate marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_f2_m1 <- cregg::cj(hr_survey, outcome3 ~ perp + agent + type + scope + targ_nonstate + targ_race + targ_relig + targ_citiz + frame + elite, id = ~id, estimate = "mm")

# Subset control variables
fig_f2_m1 <- fig_f2_m1[fig_f2_m1$feature %in% control_vars,]
fig_f2_m1 <- fig_f2_m1[fig_f2_m1$level!="A Democrat member of Congress",]
fig_f2_m1 <- fig_f2_m1[fig_f2_m1$level!="A Republican member of Congress",]

# Model 2
fig_f2_m2 <- cregg::cj(hr_survey, outcome4 ~ perp + agent + type + scope + targ_nonstate + targ_race + targ_relig + targ_citiz + frame + elite, id = ~id, estimate = "mm")

# Subset control variables
fig_f2_m2 <- fig_f2_m2[fig_f2_m2$feature %in% control_vars,]
fig_f2_m2 <- fig_f2_m2[fig_f2_m2$level!="A Democrat member of Congress",]
fig_f2_m2 <- fig_f2_m2[fig_f2_m2$level!="A Republican member of Congress",]

# -----------------------------------------------------------------------------
# Prepare figures
# -----------------------------------------------------------------------------

# Combine models
fig_f2_all <- rbind(fig_f2_m1, fig_f2_m2)

# Create control variable labels
fig_f2_all <- dplyr::bind_rows(
  fig_f2_all,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome3", "outcome4"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Recode control variable values
fig_f2_all$level <- recode(fig_f2_all$level,
                           "a civilian militia group" = "Civilian militia group",
                           "a private militia group" = "Private militia group",
                           "the military" = "Military",
                           "the national guard" = "National guard",
                           "the police" = "Police",
                           "suspected terrorists" = "Suspected terrorists",
                           "criminals" = "Criminals",
                           "protesters" = "Protesters",
                           "journalists" = "Journalists",
                           "civilians" = "Civilians",
                           "Type" = "Type",
                           "arbitrary arrest" = "Arbitrary arrest",
                           "disappearance" = "Disappearance",
                           "torture" = "Torture",
                           "extrajudicial killing" = "Extrajudicial killing",
                           "two" = "Two people",
                           "six" = "Six people",
                           "twelve" = "Twelve people",
                           "twenty" = "Twenty people",
                           "none" = "None",
                           "personal" = "Personal",
                           "violent" = "Violent",
                           "The American Civil Liberties Union, an American nonprofit organization," = "ACLU",
                           "Amnesty International, an international nonprofit organization," = "Amnesty international")

# Set factor order
level_order <- c(
  "Perpetrator (agent)", "Civilian militia group", "Private militia group", "Military", "National guard", "Police",
  "Target (non-state)", "Suspected terrorists", "Criminals", "Protesters", "Journalists", "Civilians",
  "Type", "Arbitrary arrest","Disappearance", "Torture", "Extrajudicial killing",
  "Scope", "Two people", "Six people", "Twelve people", "Twenty people",
  "Framing", "None", "Personal", "Violent",
  "Elite cue (hro)", "ACLU", "Amnesty international"
)
fig_f2_all <- fig_f2_all %>%
  mutate(level = factor(level, levels = level_order) %>% fct_rev())

# Separate models
fig_f2_m1 <- filter(fig_f2_all, outcome == "outcome3")
fig_f2_m2 <- filter(fig_f2_all, outcome == "outcome4")

# -----------------------------------------------------------------------------
# Create figures
# -----------------------------------------------------------------------------

# Create panel (a) Willingness to campaign
fig_f2_m1_plot <- ggplot(fig_f2_m1, aes(x = level, y = estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2)  +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Willingness to campaign") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (b) Signed petition
fig_f2_m2_plot <- ggplot(fig_f2_m2, aes(x = level, y = estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Signed petition") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure F.2
pdf('figure_f2.pdf', width = 8.26, height = 5.82)
ggarrange(fig_f2_m1_plot, NULL, fig_f2_m2_plot,
          nrow = 1, common.legend = T, legend = "bottom", ncol=3, widths = c(1, 0.09, 1))
dev.off()